static int blktap_read_ufe_ring(tap_blkif_t *info); /*local prototypes*/
-#define BLKTAP_MINOR 0 /*/dev/xen/blktap resides at device number
- major=254, minor numbers begin at 0 */
-#define BLKTAP_DEV_MAJOR 254 /* TODO: Make major number dynamic *
- * and create devices in the kernel *
- */
+#define BLKTAP_MINOR 0 /*/dev/xen/blktap has a dynamic major */
#define BLKTAP_DEV_DIR "/dev/xen"
+static int blktap_major;
+
/* blktap IOCTLs: */
#define BLKTAP_IOCTL_KICK_FE 1
#define BLKTAP_IOCTL_KICK_BE 2 /* currently unused */
return -1;
}
case BLKTAP_IOCTL_MAJOR:
- return BLKTAP_DEV_MAJOR;
+ return blktap_major;
case BLKTAP_QUERY_ALLOC_REQS:
{
/*Create the blktap devices, but do not map memory or waitqueue*/
for(i = 0; i < MAX_TAP_DEV; i++) translate_domid[i].domid = 0xFFFF;
- ret = register_chrdev(BLKTAP_DEV_MAJOR,"blktap",&blktap_fops);
+ /* Dynamically allocate a major for this device */
+ ret = register_chrdev(0, "blktap", &blktap_fops);
blktap_dir = devfs_mk_dir(NULL, "xen", 0, NULL);
if ( (ret < 0)||(blktap_dir < 0) ) {
return -ENOMEM;
}
+ blktap_major = ret;
+
for(i = 0; i < MAX_TAP_DEV; i++ ) {
info = tapfds[i] = kzalloc(sizeof(tap_blkif_t),GFP_KERNEL);
if(tapfds[i] == NULL) return -ENOMEM;
info->pid = 0;
info->blkif = NULL;
- ret = devfs_mk_cdev(MKDEV(BLKTAP_DEV_MAJOR, i),
+ ret = devfs_mk_cdev(MKDEV(blktap_major, i),
S_IFCHR|S_IRUGO|S_IWUSR, "xen/blktap%d", i);
if(ret != 0) return -ENOMEM;
int max_timeout = MAX_TIMEOUT;
int ctlfd = 0;
+int blktap_major;
+
static int open_ctrl_socket(char *devname);
static int write_msg(int fd, int msgtype, void *ptr, void *ptr2);
static int read_msg(int fd, int msgtype, void *ptr);
if (mknod(devname, S_IFCHR|0600,
makedev(major, minor)) == 0)
DPRINTF("Created %s device\n",devname);
- } else DPRINTF("%s device already exists\n",devname);
+ } else {
+ DPRINTF("%s device already exists\n",devname);
+ /* it already exists, but is it the same major number */
+ if (((st.st_rdev>>8) & 0xff) != major) {
+ DPRINTF("%s has old major %d\n",
+ devname,
+ (unsigned int)((st.st_rdev >> 8) & 0xff));
+ /* only try again if we succed in deleting it */
+ if (!unlink(devname))
+ make_blktap_dev(devname, major, minor);
+ }
+ }
}
static int get_new_dev(int *major, int *minor, blkif_t *blkif)
DPRINTF("Found driver: [%s]\n",dtypes[i]->name);
}
+static int find_blktap_major(void)
+{
+ FILE *fp;
+ int major;
+ char device[256];
+
+ if ((fp = fopen("/proc/devices", "r")) == NULL)
+ return -1;
+
+ /* Skip title */
+ fscanf(fp,"%*s %*s\n");
+ while (fscanf(fp, "%d %255s\n", &major, device) == 2) {
+ if (strncmp("blktap", device, 6) == 0)
+ break;
+ }
+
+ fclose(fp);
+
+ if (strncmp("blktap", device, 6) == 0)
+ return major;
+
+ return -1;
+}
+
int main(int argc, char *argv[])
{
char *devname;
/*Attach to blktap0 */
asprintf(&devname,"%s/%s0", BLKTAP_DEV_DIR, BLKTAP_DEV_NAME);
- make_blktap_dev(devname,254,0);
+ blktap_major = find_blktap_major();
+ if (blktap_major < 0)
+ goto open_failed;
+ make_blktap_dev(devname,blktap_major,0);
ctlfd = open(devname, O_RDWR);
if (ctlfd == -1) {
DPRINTF("blktap0 open failed\n");